<?php
/**
* Класс авторизации пользователя
* 
* @author Larein
* @version 1.0.0 / 27.01.2011
*/
class UserIdentity extends CUserIdentity
{
    private $_id;
    private $_time;
    
    const ERROR_TIME = 3;
    const ERROR_STATUS_INVALID = 4;
    
    protected function init()
    {
       $this->setTime(Y::param('timeoutAfterFailedLoginAttempts', 600)); 
    }
    
    protected function setTime($param) 
    {
        $this->_time = $param;
    }
    
    protected function getTime()
    {
        return $this->_time;
    }
        
    /**
    * Получаем запись о пользователе из базы данных 
    */
    protected function getRecord()
    {
        $record = Yii::app()->cache->get('auth_'.$this->username);
        if ($record === false)
        {    
            // данные найдутся в любом случае. смотри rules() в модели LoginForm
            $record =   Yii::app()->db_accountserver->createCommand()
                                  ->select('acc_id, name, password, actcode')
                                  ->from('account_pending')
                                  ->where('name=:name', array(':name'=>$this->username))
                                  ->queryRow();  // queryRow(true)?
            
            $record[errorEnter] = 0;
            $record[lastErrorEnter] = '0000-00-00 00:00:00';
            Yii::app()->cache->set('auth_'.$this->username, $record, $this->getTime());
        }
        return $record;        
    }
    
    /**
    * Проверяем данные (количество ошибок и время входа) 
    */
    protected function checkRecord($record)
    {
        if($record[errorEnter] >= Y::param('limitFailedLoginAttempts', 10) && time() < strtotime($record[lastErrorEnter]) + $this->getTime()) 
        {
            return self::ERROR_TIME;
        }
                          
        if((int)$record[actcode] != 0)
        {
            return self::ERROR_STATUS_INVALID;
        }
            
        return self::ERROR_NONE;          
    }   
    
    /**
    * Обновляем в кеше количество ошибок и время последней ошибки
    */
    protected function updateAuthErrorCount($record)
    {
        $record[errorEnter]++;
        $record[lastErrorEnter] = date("Y-m-d H:i:s");
        
        // обновляем сессию и кеш
        Yii::app()->cache->set('auth_'.$this->username, $record, $this->getTime()); 
        Yii::app()->session->add('errorEnter', $record[errorEnter]);             
    }    
    
    /**
    * Аутентификация пользователя
    */
    public function authenticate()
    {
        // получаем и проверяем запись
        $record = $this->getRecord();                  
        $checkRecord = $this->checkRecord($record);
         
        if($checkRecord != self::ERROR_NONE)
        {
            return $this->errorCode=$checkRecord;
        }
        
        // проверяем пароль    
        if($record[password] !== sha1(sha1($this->password)))
        {
            $this->updateAuthErrorCount($record);  
            return $this->errorCode=self::ERROR_PASSWORD_INVALID; 
        }
         
        $this->_id = $record[acc_id];
        $this->username = $record[name];
         
        return $this->errorCode=self::ERROR_NONE;         
    }    
    
    /**
    * Возвращает ID пользователя прошедшего аутентификацию
    */
    public function getID()
    {
        return $this->_id;
    }
}